package ph.com.gs3.formalistics.presenter.fragments.views;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.json.JSONObject;

import ph.com.gs3.formalistics.R;
import ph.com.gs3.formalistics.global.constants.DocumentType;
import ph.com.gs3.formalistics.global.constants.FormContentType;
import ph.com.gs3.formalistics.global.constants.StarMark;
import ph.com.gs3.formalistics.global.utilities.logging.FLLogger;
import ph.com.gs3.formalistics.model.vo.business.User;
import ph.com.gs3.formalistics.model.vo.business.document.Document;
import ph.com.gs3.formalistics.model.vo.business.document.DocumentHeaderData;
import ph.com.gs3.formalistics.model.vo.business.document.OutgoingAction;
import ph.com.gs3.formalistics.model.vo.business.form.Form;
import ph.com.gs3.formalistics.view.document.DocumentViewContentsManager;
import ph.com.gs3.formalistics.view.document.FieldRequiredNotifier;
import android.app.Activity;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

public class DocumentViewFragment extends Fragment {

	// Constants
	public static String TAG = DocumentViewFragment.class.getSimpleName();

	public static final int DRAWABLE_STAR = R.drawable.starstrokestarred;
	public static final int DRAWABLE_UNSTAR = R.drawable.starstrokelight;

	public static final int ACTION_STAR = R.string.action_star_document;
	public static final int ACTION_UNSTAR = R.string.action_unstar_document;

	// ==================================================================
	// {{ View Fields
	private LinearLayout llActionsContainer;
	private LinearLayout llDocumentFieldsViewContainer;
	private LinearLayout llStarBusyPrompt;
	private LinearLayout llMessageContainer;
	private LinearLayout llOutgoingActionLinkContainer;

	private TextView tvMessage;

	private ProgressBar pbMessageProgress;

	private Button bMarkDocumentStar;
	private Button bOpenComments;
	// }}

	// Data Fields
	private Form form;
	private Document document;
	private OutgoingAction outgoingAction;
	private User currentUser;

	private DocumentType documentType;

	private DocumentViewActionListener listener;

	private DocumentViewContentsManager documentViewContentsManager;

	public static DocumentViewFragment createInstance(DocumentViewFragmentParameterBundle bundle) {

		DocumentViewFragment instance = new DocumentViewFragment();
		instance.form = bundle.form;
		instance.document = bundle.document;
		instance.outgoingAction = bundle.outgoingAction;
		instance.currentUser = bundle.currentUser;

		instance.documentType = bundle.documentType;
		instance.documentViewContentsManager = bundle.documentViewContentsManager;

		return instance;

	}

	// Required constructor without parameters
	public DocumentViewFragment() {}

	@Override
	public void onAttach(Activity activity) {
		super.onAttach(activity);

		try {
			listener = (DocumentViewActionListener) activity;
		} catch (ClassCastException e) {
			throw new IllegalStateException(activity.getClass().getSimpleName()
			        + " does not implement DocumentViewActionListener");
		}
	}

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

		View rootView = inflater.inflate(R.layout.fragment_document, container, false);

		initializeDefaultViews(rootView);
		initializeFormFields();

		listener.onViewReady();

		return rootView;
	}

	private void initializeDefaultViews(View rootView) {
		llActionsContainer = (LinearLayout) rootView.findViewById(R.id.Document_llActionsContainer);
		llDocumentFieldsViewContainer = (LinearLayout) rootView
		        .findViewById(R.id.Document_llDocumentFieldsViewContainer);
		llMessageContainer = (LinearLayout) rootView.findViewById(R.id.Document_llMessageContainer);
		llOutgoingActionLinkContainer = (LinearLayout) rootView
		        .findViewById(R.id.Document_llOutgoingActionLinkContainer);

		llStarBusyPrompt = (LinearLayout) rootView
		        .findViewById(R.id.Document_llMarkDocumentStarBusy);

		tvMessage = (TextView) rootView.findViewById(R.id.Document_tvMessage);

		pbMessageProgress = (ProgressBar) rootView.findViewById(R.id.Document_pbMessageProgress);

		bMarkDocumentStar = (Button) rootView.findViewById(R.id.Document_bMarkDocumentStar);
		bOpenComments = (Button) rootView.findViewById(R.id.Document_bOpenComments);

		bOpenComments.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				listener.onOpenCommentsCommand();
				getActivity().overridePendingTransition(R.animator.push_up_in,
				        R.animator.push_up_out);
			}

		});

		bMarkDocumentStar.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View arg0) {

				if (document != null) {

					displayProcessingStarMark();
					StarMark star = document.getStarMark() == StarMark.STARRED ? StarMark.UNSTARRED
					        : StarMark.STARRED;
					listener.onMarkDocumentStarCommand(star);

				} else {
					Toast.makeText(getActivity(),
					        "You cannot mark unsubmitted documents as starred", Toast.LENGTH_LONG)
					        .show();
				}

			}
		});

		llOutgoingActionLinkContainer.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				listener.onOpenIssuedOutgoingActionCommand();
			}
		});

		if (documentType == DocumentType.EXISTING_DOCUMENT) {
			displayActions();

			if (document != null) {
				if (document.getStarMark() == StarMark.STARRED) {
					displayDocumentAsStarred();
				} else {
					displayDocumentAsUnstarred();
				}
			}
		} else {
			hideActions();
		}

	}

	private void initializeFormFields() {

		DocumentHeaderData documentHeaderData = null;

		JSONObject fieldValues = new JSONObject();
		if (documentType == DocumentType.EXISTING_DOCUMENT) {
			if (document != null && document.getFieldValuesJSON() != null) {
				fieldValues = document.getFieldValuesJSON();
			}
		} else {
			if (outgoingAction != null && outgoingAction.getDocumentFieldUpdates() != null) {
				fieldValues = outgoingAction.getDocumentFieldUpdates();
			}
		}

		switch (documentType) {
			case NEW_DOCUMENT:
			case CHILD_DOCUMENT:
				// New document, get the field properties from the form
				documentHeaderData = DocumentHeaderData.createFromForm(form);
				break;
			case EXISTING_DOCUMENT:
				// Existing document on the workflow, get the field properties from the
				// document
				documentHeaderData = DocumentHeaderData.createFromDocument(document, form);

				break;
			case OUTGOING_DOCUMENT:
				documentHeaderData = DocumentHeaderData.createFromOutgoingAction(outgoingAction,
				        form);
				break;
		}

		documentViewContentsManager.setSpecialFieldsListener(getActivity());
		documentViewContentsManager.createDocumentViewsFromData(form.getActiveFormContents(),
		        fieldValues, documentHeaderData, currentUser);

		llDocumentFieldsViewContainer.addView(documentViewContentsManager
		        .getCreatedDocumentViewContentsContainer());

	}

	// ====================================================================================
	// {{ Functional Methods

	public void displayMessage(String message, boolean displayProgressBar) {

		llMessageContainer.setVisibility(View.VISIBLE);
		pbMessageProgress.setVisibility(displayProgressBar ? View.VISIBLE : View.GONE);
		tvMessage.setText(message);

	}

	public void dismissMessage() {

		// Reset the views to their defaults
		llMessageContainer.setVisibility(View.GONE);
		pbMessageProgress.setVisibility(View.GONE);
		tvMessage.setText("");

	}

	public JSONObject getUpdatedFieldValuesFromView() {
		return documentViewContentsManager.getFieldValues();
	}

	public void showOutgoingActionsPropmt(boolean show) {
		llOutgoingActionLinkContainer.setVisibility(show ? View.VISIBLE : View.GONE);
	}

	// {{ Document Star Related Functions

	public void displayProcessingStarMark() {
		bMarkDocumentStar.setVisibility(View.GONE);
		llStarBusyPrompt.setVisibility(View.VISIBLE);
	}

	public void displayDocumentAsStarred() {
		llStarBusyPrompt.setVisibility(View.GONE);
		bMarkDocumentStar.setVisibility(View.VISIBLE);

		bMarkDocumentStar.setText(ACTION_UNSTAR);
		bMarkDocumentStar.setCompoundDrawablesWithIntrinsicBounds(DRAWABLE_STAR, 0, 0, 0);

	}

	public void displayDocumentAsUnstarred() {
		llStarBusyPrompt.setVisibility(View.GONE);
		bMarkDocumentStar.setVisibility(View.VISIBLE);

		bMarkDocumentStar.setText(ACTION_STAR);
		bMarkDocumentStar.setCompoundDrawablesWithIntrinsicBounds(DRAWABLE_UNSTAR, 0, 0, 0);

	}

	public void displayErrorMarkingDocumentStar() {

		Toast.makeText(getActivity(),
		        "There was an error starring/unstarring your document, please try again later",
		        Toast.LENGTH_LONG).show();

		if (document.getStarMark() == StarMark.STARRED) {
			displayDocumentAsStarred();
		} else {
			displayDocumentAsUnstarred();
		}

	}

	// }}

	// {{ Document Actions Related Functions

	public void displayActions() {
		llActionsContainer.setVisibility(View.VISIBLE);
	}

	public void hideActions() {
		llActionsContainer.setVisibility(View.GONE);
	}

	// }}

	public DocumentViewContentsManager getDocumentViewContentsManager() {
		return documentViewContentsManager;
	}

	public static interface DocumentViewActionListener {
		public void onMarkDocumentStarCommand(StarMark star);

		public void onOpenCommentsCommand();

		public void onOpenIssuedOutgoingActionCommand();

		public void onViewReady();
	}

	public static class DocumentViewFragmentParameterBundle {

		public User currentUser;
		public Form form;
		public Document document;
		public OutgoingAction outgoingAction;
		public DocumentType documentType;
		public DocumentViewContentsManager documentViewContentsManager;

	}

}
